<script lang="ts" setup>
    import { onBeforeUnmount, ref, reactive, shallowRef } from 'vue'
    import '@wangeditor/editor/dist/css/style.css' // 引入 css

    import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
    const emits = defineEmits(['update:modelValue', 'update:delImages'])
    const props = defineProps({
        modelValue: {
            type: String,
            default: ''
        },
        //值是否含html标签
        isHtml: {
            type: Boolean,
            default: true
        },
        height: {
            type: Number,
            default: 500
        },
        name: {
            type: String,
            default: 'file'
        },
        //默认模式:default，简洁模式:simple
        mode: {
            type: String,
            default: 'default'
        },
        //图片路径模式：rel(相对路径)、abs(绝对路径)
        pathMode: {
            type: String,
            default: 'rel'
        },
        //图片上传url
        server: {
            type: String,
            default: import.meta.env.VITE_API_HOST + import.meta.env.VITE_API_IMAGE_UPLOAD
        }
    })
    const imageList = reactive<string[]>([])
    const editorRef = shallowRef()
    const valueHtml = ref(props.modelValue)
    const toolbarConfig = {}
    const editorConfig = {
        placeholder: '请输入内容...',
        MENU_CONF: {
            uploadImage: {
                server: props.server,
                headers: {
                    Authorization: 'Bearer ' + localStorage.getItem('token')
                },
                fieldName: props.name,
                maxFileSize: 5 * 1024 * 1024, // 单个文件的最大体积限制
                customInsert(res: any, insertFn: any) {
                    if (props.pathMode === 'abs') {
                        insertFn(res.data.fullPath)
                    } else {
                        insertFn(res.data.path)
                    }
                }
            },
            insertImage: {
                /**
                 * 获取删除的照片：
                 * 上传图片到编辑器，然后又把图片删除了。此时你可能想要拿到这张删除的图片，在服务器也把图片文件删了
                 * 使用 onInsertedImage 来收集所有上传或者插入的图片，记录为 imageList1
                 * 最后保存编辑器内容之前，使用 editor.getElemsByType('image') 获取当前编辑器的所有图片，记录为 imageList2
                 * 对比 imageList1 和 imageList2 ，两者的差异，就是删除过的图片
                 * @param imageNode
                 */
                onInsertedImage(imageNode: any) {
                    if (!imageNode) return
                    const { src, alt, url, href } = imageNode
                    imageList.push(src)
                }
            }
        }
    }

    // 组件销毁时，也及时销毁编辑器
    onBeforeUnmount(() => {
        const editor = editorRef.value
        if (editor == null) return
        editor.destroy()
    })
    const handleCreated = (editor: any) => {
        editorRef.value = editor // 记录 editor 实例，重要！
    }
    const handleOnChange = (editor: any) => {
        let value = editor.getHtml()
        if (!props.isHtml) {
            value = editor.getText()
        }
        const nowImageList = editor.getElemsByType('image').map((item: any) => item.src)
        const delImageList = imageList.filter((item) => !nowImageList.includes(item))
        // console.log('删除的图片：',delImageList)
        emits('update:delImages', delImageList)
        emits('update:modelValue', value)
    }
    /**
     * 编辑器失去焦点
     */
    const handleOnBlur = (editor: any) => {}
</script>

<template>
    <div class="ym-wangeditor">
        <Toolbar :defaultConfig="toolbarConfig" :editor="editorRef" :mode="mode" style="border-bottom: 1px solid #dcdfe6" />
        <Editor
            v-model="valueHtml"
            :defaultConfig="editorConfig"
            :mode="mode"
            :style="{
                height: height + 'px'
            }"
            style="overflow-y: hidden"
            @onCreated="handleCreated"
            @onChange="handleOnChange"
            @onBlur="handleOnBlur" />
    </div>
</template>

<style scoped>
    .ym-wangeditor {
        border: 1px solid #dcdfe6;
        border-radius: 2px;
        z-index: 999;
        box-shadow: 0 0 0 1px #dcdfe6 inset;
        height: 150px;
    }
</style>
